/**
 * 
 */
package junweixu.jreader;

import java.io.FileDescriptor;
import java.io.IOException;

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.net.Uri;
import android.util.DisplayMetrics;
import android.view.WindowManager;

/**
 * @author HiyJeain
 * 
 */
public class PdfPageFactory
{

    private int mNativePDF = 0;
    private boolean mUseMediaBox = false;
    private boolean mCrop = false;
    private double mH_DPI = 72.0;
    private double mV_DPI = 72.0;
    private int mRotate;
    private int mPage;
    private int mScreenWidth;
    private int mScreenHeight;
    private String mFilePath = "";
    private boolean isLast = false;
    private boolean isFirst = false;
    private AssetFileDescriptor mAssetFileDescriptor;
    private Context mContext;
    private int mPageCount;
    private double mZoomTimes = -1;
    private PointF m_sys_dpi = new PointF();

    public PdfPageFactory(Context mContext, int mScreenWidth,
            int mScreenHeight, String mFilePath, int mCurPage)
    {
        this.mScreenHeight = mScreenHeight;
        this.mScreenWidth = mScreenWidth;
        this.mFilePath = mFilePath;
        this.mPage = mCurPage;
        this.mContext = mContext;
        initConfig();
    }

    private void initConfig()
    {
        WindowManager manager = (WindowManager) mContext
                .getSystemService(Context.WINDOW_SERVICE);
        if (manager == null)
            return;
        DisplayMetrics metrics = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(metrics);
        m_sys_dpi.set(metrics.xdpi, metrics.ydpi);
    }

    public void openBook() throws IOException
    {
        mAssetFileDescriptor = mContext.getContentResolver()
                .openAssetFileDescriptor(Uri.parse("file://" + mFilePath), "r");
        mNativePDF = native_init(mAssetFileDescriptor.getFileDescriptor(), "",
                "");
        mPageCount = getNumPages();
        setDPI();
    }

    private void setDPI()
    {
        if (mZoomTimes < 0)
        {
            double k = mScreenWidth / getPageMediaWidth(mPage);

            mH_DPI = 72 * k;
            mV_DPI = 72 * k;
        } else
        {
            mH_DPI = m_sys_dpi.x * mZoomTimes;
            mV_DPI = m_sys_dpi.y * mZoomTimes;
        }
    }

    public void prePage()
    {
        mPage--;
    }

    public void nextPage()
    {
        mPage++;
    }

    public void drawPageCanvas(Canvas mCanvas)
    {
        drawPage(mCanvas, mPage);
    }

    public void drawPageSliceCanvas(Canvas mCanvas, int mSliceX, int mSliceY,
            int mSliceW, int mSliceH)
    {

        drawPageSlice(mCanvas, mPage, mSliceX, mSliceY, mSliceW, mSliceH);
    }

    public boolean isFirstPage()
    {
        if (1 == mPage)
            return true;
        return false;
    }

    public boolean isLastPage()
    {
        if (mPageCount == mPage)
            return true;
        return false;
    }

    public native double getPageMediaWidth(int page);

    public native double getPageMediaHeight(int page);

    public native double getPageCropWidth(int page);

    public native double getPageCropHeight(int page);

    public native int getPageRotate(int page);

    public native boolean isOk();

    public native int getNumPages();

    public native void drawPage(Canvas canvas, int page);

    public native void drawPages(Canvas canvas, int firstPage, int lastPage);

    public native void drawPageSlice(Canvas canvas, int page, int sliceX,
            int sliceY, int sliceW, int sliceH);

    private native int native_init(FileDescriptor fd, String ownerPassword,
            String userPassword);

    private static native void native_class_init();

    static
    {
        try
        {
            System.loadLibrary("poppler_jni");
            native_class_init();
        } catch (Throwable e)
        {
            e.printStackTrace();
        }
    }

    public void setZoomTimes(double mZoomTimes)
    {
        this.mZoomTimes = mZoomTimes;
        setDPI();

    }

    private float getRealZoomFactor()
    {
        if (mZoomTimes <= +0.0F)
        {
            return (float) (mScreenWidth * 72.0F / getPageMediaWidth(mPage) / m_sys_dpi.x);
        }

        return (float) mZoomTimes;
    }

    public void ensureOffset(PointF m_offset)
    {
        float zoom = getRealZoomFactor();

        int w = (int) (getPageMediaWidth(mPage) * m_sys_dpi.x * zoom / 72.0F);
        int h = (int) (getPageMediaHeight(mPage) * m_sys_dpi.y * zoom / 72.0F);

        if (m_offset.x > w - mScreenWidth)
            m_offset.x = w - mScreenWidth;

        if (m_offset.x < 0)
            m_offset.x = 0;

        if (m_offset.y > h - mScreenHeight)
            m_offset.y = h - mScreenHeight;

        if (m_offset.y < 0)
            m_offset.y = 0;
    }

}
